API Reference

This page collects the public Tensorial API. Use the manual pages for examples and workflows, and use this page to look up signatures and detailed behavior.

Tensor types

Tensorial values are statically sized AbstractArrays whose type records the tensor space.

  • Tensor{S, T, N, L} is the general tensor type.
  • Vec{dim, T} and Mat{m, n, T, L} are vector and matrix aliases.
  • SecondOrderTensor{dim, T, L} and FourthOrderTensor{dim, T, L} are square tensor aliases.
  • SymmetricSecondOrderTensor{dim, T, L} and SymmetricFourthOrderTensor{dim, T, L} use symmetric tensor spaces.

See Tensor Types and Spaces and Constructing Tensors for examples.

Tensorial.TensorType
Tensor{S, T, N, L}

Statically sized tensor with tensor space S, element type T, tensor order N, and L stored independent components.

The tensor space S is a tuple of ordinary dimensions and symmetry groups. For example, Tensor{Tuple{3,3}} is a general 3×3 second-order tensor, while Tensor{Tuple{@Symmetry{3,3}}} is a symmetric 3×3 second-order tensor.

source

Constructors and special tensors

Tensorial.@VecMacro
@Vec [a, b, c, d]
@Vec [i for i in 1:2]
@Vec ones(2)

A convenient macro to construct Vec.

source
Tensorial.@MatMacro
@Mat [a b c d]
@Mat [[a, b];[c, d]]
@Mat [i+j for i in 1:2, j in 1:2]
@Mat ones(2, 2)

A convenient macro to construct Mat.

source
Tensorial.@TensorMacro
@Tensor [a b; c d]
@Tensor [[a, b];[c, d]]
@Tensor [i+j for i in 1:2, j in 1:2]
@Tensor ones(2, 2, 2)

A convenient macro to construct Tensor with arbitrary dimension.

source
Base.oneFunction
one(TensorType)

Return the identity tensor associated with the tensor space represented by TensorType.

The identity tensor is defined as the linear operator that leaves a tensor unchanged under contraction. It exists only for even-order tensors whose first and second halves span the same space. For symmetric spaces, component multiplicities are accounted for accordingly.

Examples

julia> I = one(Tensor{Tuple{@Symmetry{2, 2}, @Symmetry{2, 2}}});

julia> A = rand(Tensor{Tuple{@Symmetry{2, 2}}})
2×2 SymmetricSecondOrderTensor{2, Float64, 3}:
 0.325977  0.549051
 0.549051  0.218587

julia> I ⊡₂ A
2×2 SymmetricSecondOrderTensor{2, Float64, 3}:
 0.325977  0.549051
 0.549051  0.218587
source
Base.zeroFunction
zero(TensorType)

Construct a zero tensor.

julia> zero(Vec{2})
2-element Vec{2, Float64}:
 0.0
 0.0

julia> zero(Mat{2,3})
2×3 Mat{2, 3, Float64, 6}:
 0.0  0.0  0.0
 0.0  0.0  0.0
source
Tensorial.levicivitaFunction
levicivita(::Val{N} = Val(3))

Return N dimensional Levi-Civita tensor.

Examples

julia> ϵ = levicivita()
3×3×3 Tensor{Tuple{3, 3, 3}, Int64, 3, 27}:
[:, :, 1] =
 0   0  0
 0   0  1
 0  -1  0

[:, :, 2] =
 0  0  -1
 0  0   0
 1  0   0

[:, :, 3] =
  0  1  0
 -1  0  0
  0  0  0
source

Symmetry API

Tensorial.SymmetryType
Symmetry{S}
Symmetry(dims...)

Symmetric index group used in tensor spaces.

All dimensions in one symmetry group must be equal. In type-level tensor spaces, the usual spelling is @Symmetry.

Examples

julia> Symmetry(3, 3)
Symmetry(3, 3)
source
Tensorial.@SymmetryMacro
@Symmetry{dim, dim, ...}

Type-level spelling for a symmetric index group.

Use it inside Tensor{Tuple{...}} when several neighboring tensor indices are symmetric.

Examples

julia> S = rand(Tensor{Tuple{@Symmetry{3,3}}});

julia> S isa SymmetricSecondOrderTensor{3}
true
source
Tensorial.symmetricFunction
symmetric(::AbstractSecondOrderTensor)
symmetric(::AbstractSecondOrderTensor, uplo)

Compute the symmetric part of a second order tensor.

Examples

julia> x = rand(Mat{3,3})
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
 0.325977  0.894245  0.953125
 0.549051  0.353112  0.795547
 0.218587  0.394255  0.49425

julia> symmetric(x)
3×3 SymmetricSecondOrderTensor{3, Float64, 6}:
 0.325977  0.721648  0.585856
 0.721648  0.353112  0.594901
 0.585856  0.594901  0.49425

julia> symmetric(x, :U)
3×3 SymmetricSecondOrderTensor{3, Float64, 6}:
 0.325977  0.894245  0.953125
 0.894245  0.353112  0.795547
 0.953125  0.795547  0.49425
source
Tensorial.skewFunction
skew(A)

Compute skew-symmetric (anti-symmetric) part of a second order tensor.

Examples

julia> x = rand(Mat{3,3})
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
 0.325977  0.894245  0.953125
 0.549051  0.353112  0.795547
 0.218587  0.394255  0.49425

julia> symmetric(x) + skew(x) ≈ x
true
source
skew(ω::Vec{3})

Construct a skew-symmetric (anti-symmetric) tensor W from a vector ω as

\[\bm{\omega} = \begin{Bmatrix} \omega_1 \\ \omega_2 \\ \omega_3 \end{Bmatrix}, \quad \bm{W} = \begin{bmatrix} 0 & -\omega_3 & \omega_2 \\ \omega_3 & 0 & -\omega_1 \\ -\omega_2 & \omega_1 & 0 \end{bmatrix}\]

Examples

julia> skew(Vec(1,2,3))
3×3 Tensor{Tuple{3, 3}, Int64, 2, 9}:
  0  -3   2
  3   0  -1
 -2   1   0
source
Tensorial.minorsymmetricFunction
minorsymmetric(::AbstractFourthOrderTensor) -> SymmetricFourthOrderTensor

Compute the minor symmetric part of a fourth order tensor.

Examples

julia> x = rand(Tensor{Tuple{3,3,3,3}});

julia> minorsymmetric(x) ≈ @einsum (i,j,k,l) -> (x[i,j,k,l] + x[j,i,k,l] + x[i,j,l,k] + x[j,i,l,k]) / 4
true
source

Core operations

LinearAlgebra.crossFunction
cross(x::Vec, y::Vec)
x × y

Compute the cross product between two vectors. The infix operation x × y (where × can be typed by \times<tab>) is a synonym for cross(x, y).

Examples

julia> x = rand(Vec{3})
3-element Vec{3, Float64}:
 0.32597672886359486
 0.5490511363155669
 0.21858665481883066

julia> y = rand(Vec{3})
3-element Vec{3, Float64}:
 0.8942454282009883
 0.35311164439921205
 0.39425536741585077

julia> x × y
3-element Vec{3, Float64}:
  0.13928086435138393
  0.0669520417303531
 -0.37588028973385323
source
LinearAlgebra.normFunction
norm(::AbstractTensor)

Compute norm of a tensor.

Examples

julia> x = rand(Mat{3, 3})
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
 0.325977  0.894245  0.953125
 0.549051  0.353112  0.795547
 0.218587  0.394255  0.49425

julia> norm(x)
1.8223398556552728
source
LinearAlgebra.trFunction
tr(A)

Compute the trace of a square tensor A.

Examples

julia> A = rand(Mat{3,3})
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
 0.325977  0.894245  0.953125
 0.549051  0.353112  0.795547
 0.218587  0.394255  0.49425

julia> tr(A)
1.1733382401532275
source
Base.invFunction
inv(A)

Return the inverse of A.

Tensorial treats an even-order tensor as a linear operator: the second half of the indices is the input space, and the first half is the output space. inv(A) is defined when those two spaces match and A stores a full n × n operator on that space, where n is the number of independent components. For symmetric tensor spaces, component multiplicities are accounted for in this operator representation.

Examples

julia> x = rand(Mat{3,3})
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
 0.325977  0.894245  0.953125
 0.549051  0.353112  0.795547
 0.218587  0.394255  0.49425

julia> inv(x) * x ≈ one(x)
true

julia> A = rand(SymmetricFourthOrderTensor{3});

julia> A ⊡₂ inv(A) ≈ one(A)
true
source
Tensorial.contractFunction
contract(x, y, ::Val{N})

Conduct contraction of N inner indices. For example, N=2 contraction for third-order tensors $A_{ij} = B_{ikl} C_{klj}$ can be computed as follows:

Examples

julia> B = rand(Tensor{Tuple{3,3,3}});

julia> C = rand(Tensor{Tuple{3,3,3}});

julia> A = contract(B, C, Val(2))
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
 3.70978  2.47156  3.91807
 2.90966  2.30881  3.25965
 1.78391  1.38714  2.2079

The following infix operators are also available for specific contractions:

  • x ⊡ y (where can be typed by \boxdot<tab> ): contract(x, y, Val(1))
  • x ⊡₂ y (where ⊡₂ can be typed by \boxdot<tab>\_2<tab> ): contract(x, y, Val(2))
  • x ⊗ y (where can be typed by \otimes<tab> ): contract(x, y, Val(0))
source
contract(x, y, Val(xdims), Val(ydims))

Perform contraction over the given dimensions.

Examples

julia> A = rand(Mat{3,3})
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
 0.325977  0.894245  0.953125
 0.549051  0.353112  0.795547
 0.218587  0.394255  0.49425

julia> B = rand(Mat{3,3})
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
 0.748415  0.00744801  0.682533
 0.578232  0.199377    0.956741
 0.727935  0.439243    0.647855

julia> contract(A, B, Val(1), Val(2)) ≈ @einsum A[k,i] * B[j,k]
true

julia> contract(A, B, Val((1,2)), Val((2,1))) ≈ @einsum A[i,j] * B[j,i]
true
source
TensorCore.tensorFunction
tensor(x::AbstractTensor, y::AbstractTensor)
x ⊗ y

Compute tensor product such as $A_{ij} = x_i y_j$. x ⊗ y (where can be typed by \otimes<tab>) is a synonym for tensor(x, y).

Examples

julia> x = rand(Vec{3})
3-element Vec{3, Float64}:
 0.32597672886359486
 0.5490511363155669
 0.21858665481883066

julia> y = rand(Vec{3})
3-element Vec{3, Float64}:
 0.8942454282009883
 0.35311164439921205
 0.39425536741585077

julia> A = x ⊗ y
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
 0.291503  0.115106   0.128518
 0.490986  0.193876   0.216466
 0.19547   0.0771855  0.086179
source
Base.:^Function
x^⊗(n)

n-fold tensor product of a tensor x.

Examples

julia> x = rand(Vec{2})
2-element Vec{2, Float64}:
 0.32597672886359486
 0.5490511363155669

julia> x^⊗(3)
2×2×2 Tensor{Tuple{Symmetry{Tuple{2, 2, 2}}}, Float64, 3, 4}:
[:, :, 1] =
 0.0346386  0.0583426
 0.0583426  0.098268

[:, :, 2] =
 0.0583426  0.098268
 0.098268   0.165515
source
Tensorial.@einsumMacro
@einsum [TensorType] expr

Performs tensor computations using the Einstein summation convention. Since @einsum cannot fully infer tensor symmetries, it is possible to annotate the returned tensor type (though this is not checked for correctness). This can help eliminate the computation of the symmetric part, improving performance.

The expr can be an anonymous function, in which case the arguments of the anonymous function are treated as free indices. If no arguments are provided, the free indices are inferred based on the order in which they appear from left to right.

Examples

julia> A = rand(Mat{3,3});

julia> B = rand(Mat{3,3});

julia> (@einsum C[i,j] := A[j,k] * B[k,i]) ≈ (A * B)'
true

julia> (@einsum c := A[i,j] * A[i,j]) ≈ A ⋅ A
true

julia> (@einsum SymmetricSecondOrderTensor{3} D[i,j] := A[k,i] * A[k,j]) ≈ A' * A
true

julia> (@einsum (i,j) -> A[j,k] * B[k,i]) ≈ (A * B)'
true

julia> (@einsum A[i,j] * A[i,j]) ≈ A ⋅ A
true

julia> (@einsum SymmetricSecondOrderTensor{3} A[k,i] * A[k,j]) ≈ A' * A
true
source

Continuum mechanics API

Tensorial.volFunction
vol(A)

Compute the volumetric part of a square tensor A. This is only available in 3D.

Examples

julia> x = rand(Mat{3,3})
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
 0.325977  0.894245  0.953125
 0.549051  0.353112  0.795547
 0.218587  0.394255  0.49425

julia> vol(x)
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
 0.391113  0.0       0.0
 0.0       0.391113  0.0
 0.0       0.0       0.391113

julia> vol(x) + dev(x) ≈ x
true
source
vol(::AbstractVec{3})

Compute the volumetric part of a vector (assuming principal values of stresses and strains). This is only available in 3D.

Examples

julia> x = rand(Vec{3})
3-element Vec{3, Float64}:
 0.32597672886359486
 0.5490511363155669
 0.21858665481883066

julia> vol(x)
3-element Vec{3, Float64}:
 0.3645381733326641
 0.3645381733326641
 0.3645381733326641

julia> vol(x) + dev(x) ≈ x
true
source
vol(::Type{FourthOrderTensor{3}})
vol(::Type{SymmetricFourthOrderTensor{3}})

Construct volumetric fourth order identity tensor. This is only available in 3D.

Examples

julia> x = rand(Mat{3,3});

julia> I_vol = vol(FourthOrderTensor{3});

julia> I_vol ⊡₂ x ≈ vol(x)
true

julia> vol(FourthOrderTensor{3}) + dev(FourthOrderTensor{3}) ≈ one(FourthOrderTensor{3})
true
source
Tensorial.devFunction
dev(::AbstractSecondOrderTensor{3})
dev(::AbstractSymmetricSecondOrderTensor{3})

Compute the deviatoric part of a square tensor. This is only available in 3D.

Examples

julia> x = rand(Mat{3,3})
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
 0.325977  0.894245  0.953125
 0.549051  0.353112  0.795547
 0.218587  0.394255  0.49425

julia> dev(x)
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
 -0.065136   0.894245   0.953125
  0.549051  -0.0380011  0.795547
  0.218587   0.394255   0.103137

julia> tr(dev(x))
5.551115123125783e-17
source
dev(::AbstractVec{3})

Compute the deviatoric part of a vector (assuming principal values of stresses and strains). This is only available in 3D.

Examples

julia> x = rand(Vec{3})
3-element Vec{3, Float64}:
 0.32597672886359486
 0.5490511363155669
 0.21858665481883066

julia> dev(x)
3-element Vec{3, Float64}:
 -0.03856144446906923
  0.18451296298290282
 -0.14595151851383342

julia> vol(x) + dev(x) ≈ x
true
source
dev(::Type{FourthOrderTensor{3}})
dev(::Type{SymmetricFourthOrderTensor{3}})

Construct deviatoric fourth order identity tensor. This is only available in 3D.

Examples

julia> x = rand(Mat{3,3});

julia> I_dev = dev(FourthOrderTensor{3});

julia> I_dev ⊡₂ x ≈ dev(x)
true

julia> vol(FourthOrderTensor{3}) + dev(FourthOrderTensor{3}) ≈ one(FourthOrderTensor{3})
true
source
Tensorial.vonmisesFunction
vonmises(::AbstractSymmetricSecondOrderTensor{3})

Compute the von Mises stress.

\[q = \sqrt{\frac{3}{2} \mathrm{dev}(\bm{\sigma}) : \mathrm{dev}(\bm{\sigma})} = \sqrt{3J_2}\]

Examples

julia> σ = rand(SymmetricSecondOrderTensor{3})
3×3 SymmetricSecondOrderTensor{3, Float64, 6}:
 0.325977  0.549051  0.218587
 0.549051  0.894245  0.353112
 0.218587  0.353112  0.394255

julia> vonmises(σ)
1.3078860814690232
source
Tensorial.stress_invariantsFunction
stress_invariants(::AbstractSecondOrderTensor{3})
stress_invariants(::AbstractSymmetricSecondOrderTensor{3})
stress_invariants(::Vec{3})

Return a tuple storing stress invariants.

\[\begin{aligned} I_1(\bm{\sigma}) &= \mathrm{tr}(\bm{\sigma}) \\ I_2(\bm{\sigma}) &= \frac{1}{2} (\mathrm{tr}(\bm{\sigma})^2 - \mathrm{tr}(\bm{\sigma}^2)) \\ I_3(\bm{\sigma}) &= \det(\bm{\sigma}) \end{aligned}\]

Examples

julia> σ = rand(SymmetricSecondOrderTensor{3})
3×3 SymmetricSecondOrderTensor{3, Float64, 6}:
 0.325977  0.549051  0.218587
 0.549051  0.894245  0.353112
 0.218587  0.353112  0.394255

julia> I₁, I₂, I₃ = stress_invariants(σ)
(1.6144775244804341, 0.2986572249840249, -0.0025393241133506677)
source
Tensorial.deviatoric_stress_invariantsFunction
deviatoric_stress_invariants(::AbstractSecondOrderTensor{3})
deviatoric_stress_invariants(::AbstractSymmetricSecondOrderTensor{3})
deviatoric_stress_invariants(::Vec{3})

Return a tuple storing deviatoric stress invariants.

\[\begin{aligned} J_1(\bm{\sigma}) &= \mathrm{tr}(\mathrm{dev}(\bm{\sigma})) = 0 \\ J_2(\bm{\sigma}) &= \frac{1}{2} \mathrm{tr}(\mathrm{dev}(\bm{\sigma})^2) \\ J_3(\bm{\sigma}) &= \frac{1}{3} \mathrm{tr}(\mathrm{dev}(\bm{\sigma})^3) \end{aligned}\]

Examples

julia> σ = rand(SymmetricSecondOrderTensor{3})
3×3 SymmetricSecondOrderTensor{3, Float64, 6}:
 0.325977  0.549051  0.218587
 0.549051  0.894245  0.353112
 0.218587  0.353112  0.394255

julia> J₁, J₂, J₃ = deviatoric_stress_invariants(σ)
(0.0, 0.5701886673667987, 0.14845380911930367)
source

Rotations and quaternions

Tensorial.rotmatxFunction
rotmatx(θ::Number)

Construct rotation matrix around x axis.

\[\bm{R}_x = \begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos{\theta} & -\sin{\theta} \\ 0 & \sin{\theta} & \cos{\theta} \end{bmatrix}\]

source
Tensorial.rotmatyFunction
rotmaty(θ::Number)

Construct rotation matrix around y axis.

\[\bm{R}_y = \begin{bmatrix} \cos{\theta} & 0 & \sin{\theta} \\ 0 & 1 & 0 \\ -\sin{\theta} & 0 & \cos{\theta} \end{bmatrix}\]

source
Tensorial.rotmatzFunction
rotmatz(θ::Number)

Construct rotation matrix around z axis.

\[\bm{R}_z = \begin{bmatrix} \cos{\theta} & -\sin{\theta} & 0 \\ \sin{\theta} & \cos{\theta} & 0 \\ 0 & 0 & 1 \end{bmatrix}\]

source
Tensorial.rotmatFunction
rotmat(θ::Number)

Construct 2D rotation matrix.

\[\bm{R} = \begin{bmatrix} \cos{\theta} & -\sin{\theta} \\ \sin{\theta} & \cos{\theta} \end{bmatrix}\]

Examples

julia> rotmat(deg2rad(30))
2×2 Tensor{Tuple{2, 2}, Float64, 2, 4}:
 0.866025  -0.5
 0.5        0.866025
source
rotmat(θ::Vec{3}; sequence::Symbol)

Convert Euler angles to rotation matrix. Use 3 characters belonging to the set (X, Y, Z) for intrinsic rotations, or (x, y, z) for extrinsic rotations.

Examples

julia> α, β, γ = map(deg2rad, rand(3));

julia> rotmat(Vec(α,β,γ), sequence = :XYZ) ≈ rotmatx(α) * rotmaty(β) * rotmatz(γ)
true

julia> rotmat(Vec(α,β,γ), sequence = :xyz) ≈ rotmatz(γ) * rotmaty(β) * rotmatx(α)
true

julia> rotmat(Vec(α,β,γ), sequence = :XYZ) ≈ rotmat(Vec(γ,β,α), sequence = :zyx)
true
source
rotmat(θ, n::Vec)

Construct rotation matrix from angle θ and axis n. n must be a unit vector.

Examples

julia> x = Vec(1.0, 0.0, 0.0)
3-element Vec{3, Float64}:
 1.0
 0.0
 0.0

julia> n = Vec(0.0, 0.0, 1.0)
3-element Vec{3, Float64}:
 0.0
 0.0
 1.0

julia> rotmat(π/2, n) * x
3-element Vec{3, Float64}:
 6.123233995736766e-17
 1.0
 0.0
source
rotmat(::Quaternion)

Construct rotation matrix from quaternion.

Examples

julia> q = quaternion(π/4, Vec(0,0,1))
0.9238795325112867 + 0.0𝙞 + 0.0𝙟 + 0.3826834323650898𝙠

julia> rotmat(q)
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
 0.707107  -0.707107  0.0
 0.707107   0.707107  0.0
 0.0        0.0       1.0
source
Tensorial.rotateFunction
rotate(x, R::SecondOrderTensor)

Rotate x using the rotation matrix R. Supported inputs are vectors and second- and fourth-order tensors; symmetric tensor types are rotated into the corresponding symmetric tensor type.

Examples

julia> R = rotmatz(π/4)
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
 0.707107  -0.707107  0.0
 0.707107   0.707107  0.0
 0.0        0.0       1.0

julia> rotate(Vec(1,0,0), R)
3-element Vec{3, Float64}:
 0.7071067811865476
 0.7071067811865475
 0.0

julia> A = rand(SymmetricSecondOrderTensor{3})
3×3 SymmetricSecondOrderTensor{3, Float64, 6}:
 0.325977  0.549051  0.218587
 0.549051  0.894245  0.353112
 0.218587  0.353112  0.394255

julia> rotate(A, R) ≈ R * A * R'
true
source
rotate(x::Vec, q::Quaternion)

Rotate x by quaternion q.

Examples

julia> v = Vec(1.0, 0.0, 0.0)
3-element Vec{3, Float64}:
 1.0
 0.0
 0.0

julia> rotate(v, quaternion(π/4, Vec(0,0,1)))
3-element Vec{3, Float64}:
 0.7071067811865475
 0.7071067811865476
 0.0
source
Tensorial.angleaxisFunction
angleaxis(R::SecondOrderTensor{3})

Convert a 3D rotation matrix to an angle-axis pair (θ, n). R is assumed to be a rotation matrix; orthogonality and determinant are not validated.

source
angleaxis(::Quaternion)

Convert a quaternion to an angle-axis pair (θ, n).

source
Tensorial.QuaternionType

Quaternion represents $q_w + q_x \bm{i} + q_y \bm{j} + q_z \bm{k}$. The scalar part and vector part can be accessed by q.scalar and q.vector, respectively.

Examples

julia> Quaternion(1,2,3,4)
1 + 2𝙞 + 3𝙟 + 4𝙠

julia> Quaternion(1)
1 + 0𝙞 + 0𝙟 + 0𝙠

julia> Quaternion(Vec(1,2,3))
0 + 1𝙞 + 2𝙟 + 3𝙠

See also quaternion.

Note

Quaternion is experimental and could change or disappear in future versions of Tensorial.

source
Tensorial.quaternionFunction
quaternion(θ, n::Vec)

Construct Quaternion from angle θ and axis n as

\[q = \cos\frac{\theta}{2} + \bm{n} \sin\frac{\theta}{2}\]

n must be a unit vector.

Examples

julia> q = quaternion(π/4, Vec(0,0,1))
0.9238795325112867 + 0.0𝙞 + 0.0𝙟 + 0.3826834323650898𝙠

julia> x = rand(Vec{3})
3-element Vec{3, Float64}:
 0.32597672886359486
 0.5490511363155669
 0.21858665481883066

julia> (q * x / q).vector ≈ rotmatz(π/4) * x
true
source
Base.expMethod
exp(::Quaternion)

Compute the exponential of quaternion as

\[\exp(q) = e^{q_w} \left( \cos\| \bm{v} \| + \frac{\bm{v}}{\| \bm{v} \|} \sin\| \bm{v} \| \right)\]

source
Base.logMethod
log(::Quaternion)

Compute the logarithm of quaternion as

\[\ln(q) = \ln\| q \| + \frac{\bm{v}}{\| \bm{v} \|} \arccos\frac{q_w}{\| q \|}\]

source

Spectral functions

Base.sqrtMethod
sqrt(A::AbstractSymmetricSecondOrderTensor)

Compute the principal square root of a symmetric second-order tensor.

For an eigendecomposition,

\[\bm{A} = \bm{Q} \operatorname{diag}(\lambda_i) \bm{Q}^\mathsf{T}, \quad \sqrt{\bm{A}} = \bm{Q} \operatorname{diag}(\sqrt{\lambda_i}) \bm{Q}^\mathsf{T}.\]

The result is a SymmetricSecondOrderTensor. Automatic differentiation is defined as a spectral tensor function, including repeated eigenvalues.

source
Base.expMethod
exp(A::AbstractSymmetricSecondOrderTensor)

Compute the exponential of a symmetric second-order tensor.

For an eigendecomposition,

\[\bm{A} = \bm{Q} \operatorname{diag}(\lambda_i) \bm{Q}^\mathsf{T}, \quad \exp(\bm{A}) = \bm{Q} \operatorname{diag}(\exp(\lambda_i)) \bm{Q}^\mathsf{T}.\]

The result is a SymmetricSecondOrderTensor. Automatic differentiation is defined as a spectral tensor function, including repeated eigenvalues.

source
Base.logMethod
log(A::AbstractSymmetricSecondOrderTensor)

Compute the principal logarithm of a symmetric second-order tensor.

For an eigendecomposition,

\[\bm{A} = \bm{Q} \operatorname{diag}(\lambda_i) \bm{Q}^\mathsf{T}, \quad \log(\bm{A}) = \bm{Q} \operatorname{diag}(\log(\lambda_i)) \bm{Q}^\mathsf{T}.\]

The result is a SymmetricSecondOrderTensor. Automatic differentiation is defined as a spectral tensor function, including repeated eigenvalues.

source

Automatic differentiation API

Tensorial.∂Type
∂{N}

An operator representing the Nth-order partial derivative.

∂{N} is callable. Applying it to a function f and its arguments computes Nth-order partial derivatives of f by automatic differentiation. ∂(f, args...) is equivalent to ∂{1}(f, args...).

If pseudo keyword :all is given as the last argument, derivatives of all orders up to N are returned together with the function value. For example, ∂{N}(f, x, :all) returns (∂{N}(f,x), ..., ∂{2}(f,x), ∂{1}(f,x), f(x)).

source

Direct sum API

Tensorial.DirectSumArrayType
DirectSumArray{Axes, T, N, L}

Container for an element of a direct-sum space stored in Mandel-flat coordinates.

Type parameters

  • Axes: block-space layout along each axis
  • T: scalar storage type
  • N: block-array dimension
  • L: total number of flat stored entries

Notes

  • size(A) returns the block size.
  • flatsize(A) returns the size of the flat Mandel storage.
source
Tensorial.packFunction
pack(args...)

Construct a DirectSumArray from the blocks of a direct-sum space.

Each argument is interpreted as one block of the direct sum. Scalar blocks are stored directly. Tensor blocks are flattened and concatenated into the internal storage. If a block belongs to a symmetric tensor space, Mandel coordinates are used internally.

(typed by \oplus<tab> ) is provided as an alias for pack.

See also: unpack, flatview

Examples

julia> A = @Mat [1.0 2.0; 3.0 4.0]
2×2 Tensor{Tuple{2, 2}, Float64, 2, 4}:
 1.0  2.0
 3.0  4.0

julia> x = pack(A, 3.0)
2-element DirectSumVector with storage Float64:
 Space(2, 2)
 Space()

julia> As = symmetric(A)
2×2 SymmetricSecondOrderTensor{2, Float64, 3}:
 1.0  2.5
 2.5  4.0

julia> v = @Vec [4.0, 5.0]
2-element Vec{2, Float64}:
 4.0
 5.0

julia> y = As ⊕ 3.0 ⊕ v
3-element DirectSumVector with storage Float64:
 Space(Symmetry(2, 2),)
 Space()
 Space(2,)
source
Tensorial.unpackFunction
unpack(A::DirectSumArray)

Return the blocks stored in a DirectSumArray.

unpack(A) returns all direct-sum blocks as a tuple. unpack(A, I...) returns the block at block index I. Tensor blocks are reconstructed from the internal flat storage. For symmetric tensor blocks, the internally stored Mandel coordinates are converted back to the corresponding tensor values.

At the level of block values, unpack is the inverse of pack.

Info

unpack(A) is type-stable, but unpack(A, I...) may be type-unstable if the block index is not known at compile time, since different block indices may correspond to different return types. It is therefore most suitable when I is a constant and constant propagation can resolve the selected block.

See also: pack, flatview

Examples

julia> A = symmetric(@Mat [1.0 2.0; 3.0 4.0])
2×2 SymmetricSecondOrderTensor{2, Float64, 3}:
 1.0  2.5
 2.5  4.0

julia> x = pack(A, 3.0)
2-element DirectSumVector with storage Float64:
 Space(Symmetry(2, 2),)
 Space()

julia> unpack(x)
([1.0 2.5; 2.5 4.0], 3.0)

julia> unpack(x, 1)
2×2 SymmetricSecondOrderTensor{2, Float64, 3}:
 1.0  2.5
 2.5  4.0

julia> unpack(x, 2)
3.0
source
Tensorial.flatviewFunction
flatview(A::DirectSumArray)

Return A as a flat coordinate array. Symmetric tensor blocks are represented in Mandel coordinates.

See also: pack, unpack

Examples

julia> A = @Mat [1.0 2.0; 3.0 4.0]
2×2 Tensor{Tuple{2, 2}, Float64, 2, 4}:
 1.0  2.0
 3.0  4.0

julia> x = pack(A, 3.0)
2-element DirectSumVector with storage Float64:
 Space(2, 2)
 Space()

julia> flatview(x)
5-element StaticArraysCore.SVector{5, Float64} with indices SOneTo(5):
 1.0
 3.0
 2.0
 4.0
 3.0

julia> As = symmetric(A)
2×2 SymmetricSecondOrderTensor{2, Float64, 3}:
 1.0  2.5
 2.5  4.0

julia> y = pack(As, 3.0)
2-element DirectSumVector with storage Float64:
 Space(Symmetry(2, 2),)
 Space()

julia> flatview(y)
4-element StaticArraysCore.SVector{4, Float64} with indices SOneTo(4):
 1.0
 3.5355339059327378
 4.0
 3.0
source
Tensorial.flatsizeFunction
flatsize(A::DirectSumArray)
flatsize(::Type{<:DirectSumArray})

Return the size of the flat Mandel-coordinate storage.

This differs from size(A), which returns the block size.

Examples

julia> A = symmetric(@Mat [1.0 2.0; 2.0 4.0]);

julia> x = pack(A, 3.0);

julia> size(x)
(2,)

julia> flatsize(x)
(4,)
source

Voigt and Mandel API

Tensorial.tovoigtFunction
tovoigt(A::Union{SecondOrderTensor, FourthOrderTensor}; [order])
tovoigt(A::Union{SymmetricSecondOrderTensor, SymmetricFourthOrderTensor}; [order, offdiagonal])

Convert a tensor to Voigt form.

Keyword arguments:

  • offdiagscale: Determines the scaling factor for the offdiagonal elements.
  • order: A vector of cartesian indices (Tuple{Int, Int}) determining the Voigt order. The default order is [(1,1), (2,2), (3,3), (2,3), (1,3), (1,2), (3,2), (3,1), (2,1)] for dim=3.

See also fromvoigt.

Examples

julia> x = Mat{3,3}(1:9...)
3×3 Tensor{Tuple{3, 3}, Int64, 2, 9}:
 1  4  7
 2  5  8
 3  6  9

julia> tovoigt(x)
9-element StaticArraysCore.SVector{9, Int64} with indices SOneTo(9):
 1
 5
 9
 8
 7
 4
 6
 3
 2

julia> x = SymmetricSecondOrderTensor{3}(1:6...)
3×3 SymmetricSecondOrderTensor{3, Int64, 6}:
 1  2  3
 2  4  5
 3  5  6

julia> tovoigt(x; offdiagscale = 2,
                  order = [(1,1), (2,2), (3,3), (1,2), (1,3), (2,3)])
6-element StaticArraysCore.SVector{6, Int64} with indices SOneTo(6):
  1
  4
  6
  4
  6
 10
source
Tensorial.tomandelFunction
tomandel(A::Union{SymmetricSecondOrderTensor, SymmetricFourthOrderTensor})

Convert a tensor to Mandel form which is equivalent to tovoigt(A, offdiagscale = √2).

See also tovoigt.

source
Tensorial.fromvoigtFunction
fromvoigt(S::Type{<: Union{SecondOrderTensor, FourthOrderTensor}}, A::AbstractArray{T}; [order])
fromvoigt(S::Type{<: Union{SymmetricSecondOrderTensor, SymmetricFourthOrderTensor}}, A::AbstractArray{T}; [order, offdiagscale])

Converts an array A stored in Voigt format to a Tensor of type S.

Keyword arguments:

  • offdiagscale: Determines the scaling factor for the offdiagonal elements.
  • order: A vector of cartesian indices (Tuple{Int, Int}) determining the Voigt order. The default order is [(1,1), (2,2), (3,3), (2,3), (1,3), (1,2), (3,2), (3,1), (2,1)] for dim=3.
Note

Since offdiagscale is the scaling factor for the offdiagonal elements in Voigt form, they are multiplied by 1/offdiagscale in fromvoigt unlike tovoigt. Thus fromvoigt(tovoigt(x, offdiagscale = 2), offdiagscale = 2) returns original x.

See also tovoigt.

Examples

julia> fromvoigt(Mat{3,3}, 1.0:1.0:9.0)
3×3 Tensor{Tuple{3, 3}, Float64, 2, 9}:
 1.0  6.0  5.0
 9.0  2.0  4.0
 8.0  7.0  3.0

julia> fromvoigt(SymmetricSecondOrderTensor{3},
                 1.0:1.0:6.0,
                 offdiagscale = 2.0,
                 order = [(1,1), (2,2), (3,3), (1,2), (1,3), (2,3)])
3×3 SymmetricSecondOrderTensor{3, Float64, 6}:
 1.0  2.0  2.5
 2.0  2.0  3.0
 2.5  3.0  3.0
source
Tensorial.frommandelFunction
frommandel(S::Type{<: Union{SymmetricSecondOrderTensor, SymmetricFourthOrderTensor}}, A::AbstractArray{T})

Create a tensor of type S from Mandel form. This is equivalent to fromvoigt(S, A, offdiagscale = √2).

See also fromvoigt.

source